﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class MapCreator : MonoBehaviour
{
    // Start is called before the first frame update
    // 生成空气墙
    public GameObject airBoundaryPrefab;
    public GameObject brickPrefab;
    public GameObject ironPrefab;
    public GameObject junglePrefab;
    public GameObject riverPrefab;
    public GameObject birthPointPrefab;
    public GameObject bonusPrefab;

    //public GameObject[] mapPrefabs;
    // NUM_ELEMENTS_X表示一行（从-MAP_HALF_X到+MAP_HALF_X，包含首位这两个坐标）最多
    // 有多少个半边长为ELEMENT_HALF_SIZE的元素。要求第一个元素以 -MAP_HALF_X为中心。
    // 这个问题等价于在[-MAP_HALF_X-MAP_HALF_X, +MAP_HALF_X+MAP_HALF_X]区间中，第一个
    // 元素顶格放置，最多放置多少个元素，这个等价问题的解就是区间长度和元素边长的比值的下整数。
    private const int NUM_ELEMENTS_X = (int)((MAP_HALF_X * 2 + ELEMENT_HALF_SIZE * 2) / (2 * ELEMENT_HALF_SIZE));
    private const int NUM_ELEMENTS_Y = (int)((MAP_HALF_Y * 2 + ELEMENT_HALF_SIZE * 2) / (2 * ELEMENT_HALF_SIZE));
    private Vector3[,] coordinateGrid = new Vector3 [NUM_ELEMENTS_X, NUM_ELEMENTS_Y];
    // 砖块的边长
    private const float ELEMENT_HALF_SIZE = 0.32f;
    // 地图的长和宽
    private const float MAP_HALF_X = 7f;
    private const float MAP_HALF_Y = 5f;

    public int numPlayers;

    public AudioClip clip_gameStart;

    private float meterialTimeVal = 0;


    void Awake()
    {
        Invoke("ChangeScene", 5);
        
        AudioSource.PlayClipAtPoint(clip_gameStart, gameObject.transform.position, 100f);
        GameObject[] mapPrefabs = {brickPrefab, ironPrefab, junglePrefab, riverPrefab};
        // 生成坐标网格数组
        for (int i = 0; i < NUM_ELEMENTS_X; i++)
        {
            for (int j = 0; j < NUM_ELEMENTS_Y; j++)
            {
                coordinateGrid[i, j] = new Vector3(-MAP_HALF_X + ELEMENT_HALF_SIZE * 2 * i, -MAP_HALF_Y + ELEMENT_HALF_SIZE * 2 * j);
            }
        }
        // 生成玩家坐标
        Vector3[] playerCoordinates = new Vector3[numPlayers];
        // numFilled记录playerCoordinates已经填充了几个玩家坐标
        int numFilled = 0;
        while (playerCoordinates.Length != numFilled)
        {
            // 随机生成一个玩家坐标
            Vector3 c = coordinateGrid[Random.Range(0, NUM_ELEMENTS_X), Random.Range(0, NUM_ELEMENTS_Y)];
            int i = 0;
            for (i = 0; i < numFilled; i++)
            {
                // 如果当前坐标已经存在，直接跳出重新生成
                if (playerCoordinates[i] == c)
                {
                    break;
                }
            }
            if (i == numFilled)
            {
                // 如果当前坐标尚不存在，加入玩家坐标列表
                playerCoordinates[numFilled++] = c;
            }
        }
        // 生成玩家出生点
        for (int i = 0; i < numPlayers; i++)
        {
            Instantiate(birthPointPrefab, playerCoordinates[i], Quaternion.Euler(new Vector3()));
        }
        // 生成地图元素
        for (int i = 0; i < NUM_ELEMENTS_X; i++)
        {
            for (int j = 0; j < NUM_ELEMENTS_Y; j++)
            {
                bool isBirthPoint = false;
                for (int k = 0; k < numPlayers; k++)
                {
                    // 如果当前位置是玩家的出生点，跳过
                    if (playerCoordinates[k] == coordinateGrid[i, j])
                    {
                        isBirthPoint = true;
                        break;
                    }
                }
                if (isBirthPoint)
                {
                    continue;
                }
                // 如果当前位置不是玩家的出生点，初始化地图元素
                if (Random.Range(0, 2) == 0)
                {
                    Instantiate(mapPrefabs[Random.Range(0, 4)], coordinateGrid[i, j], Quaternion.Euler(new Vector3()));
                }
            }
        }        
        // 生成地图边界（空气墙）
        for (float x = -8f; x <= 8f; x++)
        {
            Instantiate(airBoundaryPrefab, new Vector3(x, -6f, 0), Quaternion.Euler(new Vector3()));
            Instantiate(airBoundaryPrefab, new Vector3(x, +6f, 0), Quaternion.Euler(new Vector3()));
        }
        for (int y = -6; y <= 6; y++)
        {
            Instantiate(airBoundaryPrefab, new Vector3(-8f, y, 0), Quaternion.Euler(new Vector3()));
            Instantiate(airBoundaryPrefab, new Vector3(+8f, y, 0), Quaternion.Euler(new Vector3()));
        }
    }

    // Update is called once per frame
    void Update()
    {
        meterialTimeVal += Time.deltaTime;
        if (meterialTimeVal > 5)
        {
            meterialTimeVal = 0;
            Instantiate(bonusPrefab, new Vector3(0, 0, 0), Quaternion.Euler(new Vector3()));
        }
    }

    private void ChangeScene()
    {
        SceneManager.LoadScene(1);
    }
}
